#include <cstdio>

struct Node
{
    int h, left, right;
    
};

Node f[ 600000 ];
int n, m, p;

int max( int a, int b ) { return ( a > b )? a : b; }

int buildtree( int t, int l, int r )
{
    f[ t ].left = l;
    f[ t ].right = r;
    if ( l == r )
        return f[ t ].h;
    return f[ t ].h = max( buildtree( t * 2, l, ( l + r - 1 ) / 2 ), buildtree( t * 2 + 1, ( l + r - 1 ) / 2 + 1, r ) );
}

int query( int l, int r, int pos )
{
    if ( r < f[ pos ].left || l > f[ pos ].right )
        return 0;
    if ( l < f[ pos ].left )
        l = f[ pos ].left;
    if ( r > f[ pos ].right )
        r = f[ pos ].right;
    if ( f[ pos ].left < l || f[ pos ].right > r )
        return max( query( l, r, pos * 2 ), query( l, r, pos * 2 + 1 ) );
    return f[ pos ].h;
}

void init( )
{
    int i, dc;
    p = 1;
    while ( p <= n )
        p <<= 1;
    if ( n * 2 == p )
        p >>= 1;
    for ( i = 0; i < n; i++ )
        scanf("%d", &f[ p + i ].h);
    dc = buildtree( 1, 1, p );
}

void work( )
{
    int s, t, k, v, pos;
    char command[ 2 ];
    while ( m-- )
    {
        scanf("%s", command);
        if ( command[ 0 ] == 'Q' )
        {
            scanf("%d%d", &s, &t);
            printf("%d\n", query( s, t, 1 ));
        }
        else
        {
            scanf("%d%d", &k, &v);
            k--;
            f[ p + k ].h = v;
            pos = ( p + k ) >> 1;
            while ( pos )
            {
                f[ pos ].h = max( f[ pos * 2 ].h, f[ pos * 2 + 1 ].h );
                pos >>= 1;
            }
        }
    }
}

int main( )
{
    while ( scanf("%d%d", &n, &m) != EOF )
    {
        init( );
        work( );
    }
    return 0;
}
